package main

import "fmt"

// 自定义类型
type myInt int
type myFn func(int, int) int

// 自定义类型自定义方法
func (m myInt) printInfo() {
	fmt.Println("我是自定义类型里面的自定义方法")
}

// 类型别名
type myFloat = float64

// 结构体
type Person struct {
	name string
	age  int
	sex  string
}

// 属性匿名, 属性类型不能重复
type Person2 struct {
	string
	int
}

// 结构体方法
// XXX 普通类型, 不修改结构体中的内容
func (p Person) PrintInfo() {
	fmt.Printf("姓名:%v, 年龄:%v \n", p.name, p.age)
}

// XXX 指针类型, 可以修改结构体中的内容
func (p *Person) setInfo(name string, age int) {
	p.name = name
	p.age = age
}

func main() {
	//var a myInt = 0
	//fmt.Printf("%v, %T\n", a, a)
	//
	//var b myFloat = 12.3
	//fmt.Printf("%v, %T\n", b, b)

	// 实例化结构体
	// 第一种: 实例化Person结构体
	//var p1 Person // == var p1 = Person{}
	//p1.name = "张三"
	//p1.age = 18
	//p1.sex = "男"
	//fmt.Printf("值: %v, 类型:%T\n", p1, p1)
	//fmt.Printf("值: %#v, 类型:%T\n", p1, p1)
	//
	//// 第二种: 实例化Person结构体
	////XXX 注意：在 Golang 中支持对结构体指针直接使用.来访问结构体的成员。
	////p2.name = "张三" 其实在底层是(*p2).name = "张三"
	//var p2 = new(Person)
	//p2.name = "李四"
	//p2.age = 20
	//(*p2).sex = "女"
	//fmt.Printf("值: %#v, 类型:%T\n", p2, p2)
	//
	//// 第三种: 实例化Person结构体
	//var p3 = &Person{}
	//p3.name = "王五"
	//p3.age = 30
	//p3.sex = "男"
	//fmt.Printf("值: %#v, 类型:%T\n", p3, p3)
	//
	//// 第四种: 实例化Person结构体
	//var p4 = Person{
	//	name: "嘻嘻",
	//	age:  40,
	//	sex:  "女",
	//}
	//fmt.Printf("值: %#v, 类型:%T\n", p4, p4)
	//
	//// 第五种: 实例化Person结构体
	//var p5 = &Person{
	//	name: "哈哈",
	//	age:  50,
	//	sex:  "男",
	//}
	//fmt.Printf("值: %#v, 类型:%T\n", p5, p5)
	//
	//// 第六种: 实例化Person结构体
	//var p6 = &Person{
	//	name: "哈哈2",
	//}
	//fmt.Printf("值: %#v, 类型:%T\n", p6, p6)
	//
	//// 第七种: 实例化Person结构体
	//var p7 = &Person{
	//	"哈哈3",
	//	20,
	//	"男",
	//}
	//fmt.Printf("值: %#v, 类型:%T\n", p7, p7)

	//XXX 结构体是值类型
	//var p1 = Person{
	//	name: "张三",
	//	age:  18,
	//	sex:  "男",
	//}
	//p2 := p1
	//fmt.Printf("%#v \n", p1)
	//fmt.Printf("%#v \n", p2)
	//p2.name = "李四"
	//p2.age = 28
	//fmt.Printf("%#v \n", p1)
	//fmt.Printf("%#v \n", p2)

	//var p1 = Person{
	//	name: "张三",
	//	age:  18,
	//	sex:  "男",
	//}
	//p1.PrintInfo()

	// golang中结构体实例是独立的, 相互不影响
	//var p2 = Person{
	//	name: "李四",
	//	age:  28,
	//	sex:  "男",
	//}
	//fmt.Printf("%#v \n", p2)
	//p2.setInfo("男2", 123)
	//fmt.Printf("%#v \n", p2)

	//var myInt01 myInt
	//myInt01.printInfo()

	var p1 = Person2{
		"张三",
		18,
	}
	fmt.Printf("%#v \n", p1)
}
